package edu.gatech.cs3240.DFA;

import edu.gatech.cs3240.NFA.NFA;
import edu.gatech.cs3240.NFA.State;

public class DFA extends NFA {

	public DFA() {
		super(new State(false));
	}
	
	public DFA(State dfaStates) {
		super(dfaStates);
	}

	/**
	 * This method is overridden only to ensure that it is not called, 
	 * preventing the addition of epsilon transitions.
	 */
	public void addTransition(State source, State target) 
			throws IllegalNFAOperationException {
		throw new IllegalNFAOperationException("Attempting to add an epsilon" +
				" transition to a DFA.");
	}
	
	/**
	 * Same as method in super, but check for epsilon transitions.
	 */
	public void addAllStates(State s) throws IllegalNFAOperationException {
		if(!getAllStates().contains(s)) 
			getAllStates().add(s);
		for(int i = 0; i < s.getPaths().size(); i++) {
			if(s.getPaths().get(i).isEpsilon())
				throw new IllegalNFAOperationException("Attempting to add an" +
						" epsilon transition to a DFA.");
			else
				addAllStates(s.getPaths().get(i).getTarget());
		}
	}
	
	/**
	 * DFAs, unlike NFAs, must necessarily have the capacity for multiple 
	 * accept states.  So this is same as super's method, plus that 
	 * functionality.
	 * @param s
	 */
	public void setAccept(NFA parent, State s) throws IllegalNFAOperationException {
		if(getAllStates().contains(s) || 
				(parent.getAllStates().contains(s) && 
						parent.getAllStates().contains(getStartState()))) {
			s.setAccepting(true);
		} else 
			throw new IllegalNFAOperationException("Attempting to set a " +
					"foreign state as accept state.");
	}
	
	public State getAcceptState() {
		return null;
	}

	public void setStartState(State state) {
		startState = state;
	}
}
